package model

import (
	"context"
	"database/sql"
	"fmt"
	"time"

	"github.com/zeromicro/go-zero/core/stores/sqlx"
)

var _ FundScoreModel = (*customFundScoreModel)(nil)

type (
	// FundScoreModel 是一个接口，可以自定义添加更多方法
	FundScoreModel interface {
		fundScoreModel
		FindByCode(ctx context.Context, code string) (*FundScore, error)
	}

	customFundScoreModel struct {
		*defaultFundScoreModel
	}

	fundScoreModel interface {
		Insert(ctx context.Context, data *FundScore) (sql.Result, error)
		FindOne(ctx context.Context, id string) (*FundScore, error)
		Update(ctx context.Context, data *FundScore) error
		Delete(ctx context.Context, id string) error
	}

	defaultFundScoreModel struct {
		conn  sqlx.SqlConn
		table string
	}

	FundScore struct {
		Id           string    `db:"id"`
		FundCode     string    `db:"fund_code"`
		FundName     string    `db:"fund_name"`
		FundType     string    `db:"fund_type"`
		RiskLevel    string    `db:"risk_level"`
		Manager      string    `db:"manager"`
		Company      string    `db:"company"`
		Size         string    `db:"size"`
		Established  time.Time `db:"established"`
		TotalScore   int32     `db:"total_score"`
		ScoreType    string    `db:"score_type"`
		ProfitScore  int32     `db:"profit_score"`
		ProfitDesc   string    `db:"profit_desc"`
		RiskScore    int32     `db:"risk_score"`
		RiskDesc     string    `db:"risk_desc"`
		StableScore  int32     `db:"stable_score"`
		StableDesc   string    `db:"stable_desc"`
		RiskTip      string    `db:"risk_tip"`
		RadarLabels  string    `db:"radar_labels"` // JSON格式存储
		RadarValues  string    `db:"radar_values"` // JSON格式存储
		UpdatedAt    time.Time `db:"updated_at"`
	}
)

// NewFundScoreModel 返回数据库表模型
func NewFundScoreModel(conn sqlx.SqlConn) FundScoreModel {
	return &customFundScoreModel{
		defaultFundScoreModel: newFundScoreModel(conn),
	}
}

func newFundScoreModel(conn sqlx.SqlConn) *defaultFundScoreModel {
	return &defaultFundScoreModel{
		conn:  conn,
		table: "fund_score",
	}
}

func (m *defaultFundScoreModel) Insert(ctx context.Context, data *FundScore) (sql.Result, error) {
	query := fmt.Sprintf("insert into %s (id, fund_code, fund_name, fund_type, risk_level, manager, company, size, established, total_score, score_type, profit_score, profit_desc, risk_score, risk_desc, stable_score, stable_desc, risk_tip, radar_labels, radar_values, updated_at) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table)
	return m.conn.ExecCtx(ctx, query, data.Id, data.FundCode, data.FundName, data.FundType, data.RiskLevel, data.Manager, data.Company, data.Size, data.Established, data.TotalScore, data.ScoreType, data.ProfitScore, data.ProfitDesc, data.RiskScore, data.RiskDesc, data.StableScore, data.StableDesc, data.RiskTip, data.RadarLabels, data.RadarValues, data.UpdatedAt)
}

func (m *defaultFundScoreModel) FindOne(ctx context.Context, id string) (*FundScore, error) {
	query := fmt.Sprintf("select id, fund_code, fund_name, fund_type, risk_level, manager, company, size, established, total_score, score_type, profit_score, profit_desc, risk_score, risk_desc, stable_score, stable_desc, risk_tip, radar_labels, radar_values, updated_at from %s where id = ? limit 1", m.table)
	var resp FundScore
	err := m.conn.QueryRowCtx(ctx, &resp, query, id)
	return &resp, err
}

func (m *defaultFundScoreModel) Update(ctx context.Context, data *FundScore) error {
	query := fmt.Sprintf("update %s set fund_code = ?, fund_name = ?, fund_type = ?, risk_level = ?, manager = ?, company = ?, size = ?, established = ?, total_score = ?, score_type = ?, profit_score = ?, profit_desc = ?, risk_score = ?, risk_desc = ?, stable_score = ?, stable_desc = ?, risk_tip = ?, radar_labels = ?, radar_values = ?, updated_at = ? where id = ?", m.table)
	_, err := m.conn.ExecCtx(ctx, query, data.FundCode, data.FundName, data.FundType, data.RiskLevel, data.Manager, data.Company, data.Size, data.Established, data.TotalScore, data.ScoreType, data.ProfitScore, data.ProfitDesc, data.RiskScore, data.RiskDesc, data.StableScore, data.StableDesc, data.RiskTip, data.RadarLabels, data.RadarValues, data.UpdatedAt, data.Id)
	return err
}

func (m *defaultFundScoreModel) Delete(ctx context.Context, id string) error {
	query := fmt.Sprintf("delete from %s where id = ?", m.table)
	_, err := m.conn.ExecCtx(ctx, query, id)
	return err
}

func (m *customFundScoreModel) FindByCode(ctx context.Context, code string) (*FundScore, error) {
	query := fmt.Sprintf("select id, fund_code, fund_name, fund_type, risk_level, manager, company, size, established, total_score, score_type, profit_score, profit_desc, risk_score, risk_desc, stable_score, stable_desc, risk_tip, radar_labels, radar_values, updated_at from %s where fund_code = ? limit 1", m.table)
	var resp FundScore
	err := m.conn.QueryRowCtx(ctx, &resp, query, code)
	return &resp, err
} 